﻿/*
 * @Autor: PK
 * @Date: 2021/12/06 10:20:SS
 */

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Data;
using ShkSimulation.core.dao.input.resource;
using ShkSimulation.core.exceptions;
using ShkSimulation.core.template;

namespace ShkSimulation.core.optimization.extractor {

	public class ArrayDecisionVariableExtractor : DecisionVariableExtractor{

		private readonly ArrayCellPointGroup arrayCellPointGroup;

		public ArrayDecisionVariableExtractor(ArrayCellPointGroup locator) {
			this.arrayCellPointGroup = locator;
		}

		public double[] ExtractDecisionVariables(NetworkInputData inputData) {
			IReadOnlyDictionary<string, Resource> allInputData = inputData.AllResources;
			List<double> result = new List<double>();
			ImmutableSortedSet<string> sortedName = arrayCellPointGroup.GetSortedName();
			foreach (var identifier in sortedName) {
				if (!allInputData.ContainsKey(identifier)) {
					throw new ErrorParamException($"不存在表：{identifier}");
				}
				DataTable data = allInputData[identifier].GetDataTable();
				foreach (var each in arrayCellPointGroup.Location[identifier]) {
					if (each.Row >= data.Rows.Count || each.Column >= data.Columns.Count) {
						throw new ErrorParamException($"属性提取器超过了索引：{identifier}");
					}
					result.Add(Convert.ToDouble(data.Rows[each.Row][each.Column]));
				}
			}
			return result.ToArray();
		}

		public NetworkInputData CloneThenInjectDecisionVariables(NetworkInputData sourceData, double[] decisionVariables) {
			NetworkInputData inputData = sourceData.Clone();
			ImmutableSortedSet<string> sortedName = arrayCellPointGroup.GetSortedName();
			if (decisionVariables == null || decisionVariables.Length != sortedName.Count) {
				throw new ErrorParamException($"更新的数据：{decisionVariables} 和提取器提取属性长度不一致：{sortedName.Count}");
			}
			IReadOnlyDictionary<string, Resource> allInputData = inputData.AllResources;
			int index = 0;
			foreach (var identifier in sortedName) {
				if (!allInputData.ContainsKey(identifier)) {
					throw new ErrorParamException($"不存在表：{identifier}");
				}
				Resource resource = allInputData[identifier];
				DataTable data = resource.GetDataTable();
				foreach (var each in arrayCellPointGroup.Location[identifier]) {
					if (each.Row >= data.Rows.Count || each.Column >= data.Columns.Count) {
						throw new ErrorParamException($"属性提取器超过了索引：{identifier}");
					}
					data.Rows[each.Row][each.Column] = decisionVariables[index];
					index++;
				}
				inputData.UpdateResource(identifier, resource);
			}
			return inputData;
		}

	}
}